package com.kexio.core.data.config;

import java.time.LocalDateTime;

import org.apache.ibatis.reflection.MetaObject;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.kexio.core.security.util.UserInfoUtils;

import jakarta.annotation.PostConstruct;

/**
 * MyBatis-Plus配置类
 * 
 * 功能说明：
 * - 配置分页插件
 * - 配置字段自动填充
 * - 配置Mapper扫描
 * 
 * @author Kexio
 * @since 1.0.0
 */
@Configuration
@ConditionalOnClass(MybatisPlusInterceptor.class)
@MapperScan(basePackages = {"com.kexio.**.mapper", "com.kexio.**.dao"})
public class MyBatisConfig {

    private static final Logger log = LoggerFactory.getLogger(MyBatisConfig.class);

    @PostConstruct
    public void init() {
        log.info("==> Kexio MyBatis-Plus配置已启用");
        log.debug("MyBatis配置: 分页插件、字段自动填充、Mapper扫描");
    }

    /**
     * MyBatis-Plus插件配置
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        
        // 分页插件
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
        paginationInnerInterceptor.setDbType(DbType.POSTGRE_SQL);
        paginationInnerInterceptor.setMaxLimit(1000L); // 最大单页限制
        paginationInnerInterceptor.setOverflow(false); // 溢出总页数后是否进行处理
        
        interceptor.addInnerInterceptor(paginationInnerInterceptor);
        
        log.debug("==> MyBatis-Plus分页插件已配置: 数据库类型={}, 最大单页限制={}", 
                DbType.POSTGRE_SQL, 1000L);
        
        return interceptor;
    }

    /**
     * 字段自动填充配置
     */
    @Bean
    public MetaObjectHandler metaObjectHandler() {
        return new KexioMetaObjectHandler();
    }

    /**
     * 自定义字段自动填充处理器
     */
    public static class KexioMetaObjectHandler implements MetaObjectHandler {

        @Override
        public void insertFill(MetaObject metaObject) {
            LocalDateTime now = LocalDateTime.now();
            Long currentUserId = getCurrentUserId();
            
            // 创建时间
            this.strictInsertFill(metaObject, "createdTime", LocalDateTime.class, now);
            this.strictInsertFill(metaObject, "created_time", LocalDateTime.class, now);
            
            // 更新时间
            this.strictInsertFill(metaObject, "updatedTime", LocalDateTime.class, now);
            this.strictInsertFill(metaObject, "updated_time", LocalDateTime.class, now);
            
            // 创建者
            if (currentUserId != null) {
                this.strictInsertFill(metaObject, "createdBy", Long.class, currentUserId);
                this.strictInsertFill(metaObject, "created_by", Long.class, currentUserId);
                this.strictInsertFill(metaObject, "updatedBy", Long.class, currentUserId);
                this.strictInsertFill(metaObject, "updated_by", Long.class, currentUserId);
            }
        }

        @Override
        public void updateFill(MetaObject metaObject) {
            LocalDateTime now = LocalDateTime.now();
            Long currentUserId = getCurrentUserId();
            
            // 更新时间
            this.strictUpdateFill(metaObject, "updatedTime", LocalDateTime.class, now);
            this.strictUpdateFill(metaObject, "updated_time", LocalDateTime.class, now);
            
            // 更新者
            if (currentUserId != null) {
                this.strictUpdateFill(metaObject, "updatedBy", Long.class, currentUserId);
                this.strictUpdateFill(metaObject, "updated_by", Long.class, currentUserId);
            }
        }

        /**
         * 获取当前用户ID
         */
        private Long getCurrentUserId() {
            try {
                return UserInfoUtils.getCurrentUserId();
            } catch (Exception e) {
                // 在没有用户上下文的情况下（如系统初始化），返回null
                return null;
            }
        }
    }
}
